package com.jacky.bluetooth;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;

import androidx.annotation.NonNull;

import java.util.HashMap;

import io.flutter.Log;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
import io.flutter.plugin.common.PluginRegistry;

/**
 * BluetoothPlugin
 */
public class BluetoothPlugin implements FlutterPlugin, MethodCallHandler, ActivityAware,
        PluginRegistry.RequestPermissionsResultListener {
    /// The MethodChannel that will the communication between Flutter and native Android
    ///
    /// This local reference serves to register the plugin with the Flutter Engine and unregister it
    /// when the Flutter Engine is detached from the Activity

    public final static String UUID_KEY_UART = "00002aa1-0000-1000-8000-00805f9b34fb";
    private MethodChannel channel;
    private BluetoothManager manager;
    private Activity mContext;
    private int bluetoothStatus = BluetoothManager.IDLE;

    @Override
    public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
        BinaryMessenger messenger = flutterPluginBinding.getBinaryMessenger();
        channel = new MethodChannel(messenger, "com.jacky.util/blue");
        channel.setMethodCallHandler(this);
    }

    @Override
    public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
        String method = call.method;
        switch (method) {
            case "startWithAutoConnect":
                if (manager == null) manager = new BluetoothManager(mContext) {
                    @Override
                    protected void onValue(byte[] bytes) {
                        String value = new String(bytes);
                        channel.invokeMethod("dataCallback", value);
                    }

                    @Override
                    protected void connectionStateChange(int newState) {
                        bluetoothStatus = newState;
                        channel.invokeMethod("onUpdateState", newState);
                    }

                    @Override
                    protected void discoverPeripheral(String bluetoothName) {
                        HashMap<String, String> map = new HashMap<>();
                        map.put("name", bluetoothName);
                        channel.invokeMethod("onDiscoverPeripheral", map);
                    }
                };

                boolean showLog = call.argument("showLog");
                String bluetoothName = call.argument("name");
                String bluetoothAddress = call.argument("address");
                manager.initParams(bluetoothName,bluetoothAddress, UUID_KEY_UART, showLog);
                bluetoothStatus = manager.start();
                result.success(true);
                break;
            case "stop":
                release();
                break;
            case "reStartScan":
                if(manager != null) {
                    bluetoothStatus = manager.start();
                    manager.connectionStateChange(bluetoothStatus);
                }
                result.success(true);
                break;
            case "getStatus":
                result.success(bluetoothStatus);
                break;
            case "connectPeripheral" :
                String name = (String)call.arguments;
                manager.initParams(name, UUID_KEY_UART, false);
                bluetoothStatus = manager.start();
                result.success(true);
                break;
            default:
                result.notImplemented();
                break;
        }
    }

    private void release() {
        if (manager != null) manager.stop();
        manager = null;
        bluetoothStatus = BluetoothManager.IDLE;
    }

    @Override
    public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
        channel.setMethodCallHandler(null);
    }

    @Override
    public void onAttachedToActivity(ActivityPluginBinding binding) {
        mContext = binding.getActivity();
        binding.addRequestPermissionsResultListener(this);
    }

    @Override
    public void onDetachedFromActivityForConfigChanges() {
    }

    @Override
    public void onReattachedToActivityForConfigChanges(ActivityPluginBinding binding) {
        onAttachedToActivity(binding);
    }

    @Override
    public void onDetachedFromActivity() {
        mContext = null;
        release();
    }

    @Override
    public boolean onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        if(requestCode == BluetoothManager.REQUEST_PERSIMISSION) {
            if(grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                manager.permissionOK();
            } else {
                manager.connectionStateChange(BluetoothManager.UNAUTHORIZED);
            }
            return true;
        }
        return false;
    }
}
